package com.zmc.order.infrastructure.updater.order;

import com.zmc.common.constant.QueueConstant;
import com.zmc.common.domain.es.EsSkuAttr;
import com.zmc.common.domain.es.EsSkuEntity;
import com.zmc.common.domain.query.coupon.CouponFeignQuery;
import com.zmc.common.domain.query.goods.GoodSkuFeignQuery;
import com.zmc.common.domain.resp.coupon.CouponAllFeignResp;
import com.zmc.common.domain.resp.order.OrderReduceInventoryResp;
import com.zmc.common.domain.vo.coupon.CouponFeignVo;
import com.zmc.common.domain.vo.coupon.CouponReduceVo;
import com.zmc.common.domain.vo.coupon.FullReductionFeignVo;
import com.zmc.common.domain.vo.coupon.LadderFeignVo;
import com.zmc.common.domain.vo.good.GoodsUpVo;
import com.zmc.common.domain.vo.member.MemberInfo;
import com.zmc.common.enums.SerialCodeEnum;
import com.zmc.common.exception.base.BusinessException;
import com.zmc.common.utils.JsonUtils;
import com.zmc.common.utils.token.AuthTokenService;
import com.zmc.common.utils.uuid.IdUtils;
import com.zmc.common.utils.uuid.SnowflakeIdUtils;
import com.zmc.order.feign.CouponFeignService;
import com.zmc.order.feign.MemberFeignService;
import com.zmc.order.feign.ProductFeignService;
import com.zmc.order.feign.SearchFeignService;
import com.zmc.order.infrastructure.bean.resp.OrderSubmitResp;
import com.zmc.order.infrastructure.bean.vo.SubmitOrderVo;
import com.zmc.order.infrastructure.entity.OrderEntity;
import com.zmc.order.infrastructure.entity.OrderItemEntity;
import com.zmc.order.infrastructure.enums.OrderEnum;
import com.zmc.order.infrastructure.service.OrderItemService;
import com.zmc.order.infrastructure.service.OrderService;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author：zmc
 * @Date：2025/5/15 15:40
 * 创建订单
 */
@Component
public class OrderCreateUpdater<T> implements OderUpdater<T> {

    public static Logger log = LoggerFactory.getLogger(OrderCreateUpdater.class);

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private SearchFeignService searchFeignService;

    @Autowired
    private ProductFeignService productFeignService;

    @Autowired
    private AuthTokenService authTokenService;

    @Autowired
    private CouponFeignService couponFeignService;

    @Autowired
    private MemberFeignService memberFeignService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    @Transactional
    @ShardingSphereTransactionType(TransactionType.BASE)
    public void execute(T param) {
        SubmitOrderVo vo = (SubmitOrderVo) param;
        //查询sku列表详情
        GoodSkuFeignQuery query = new GoodSkuFeignQuery();
        query.setSkuIds(vo.getGoods().stream().map(GoodsUpVo::getSkuId).collect(Collectors.toList()));
        List<EsSkuEntity> esSkuList = JsonUtils.transToArrayClass(searchFeignService.getSkuInfosBySkuIds(query), EsSkuEntity.class);
        OrderEntity order = new OrderEntity();
        MemberInfo memberInfo = authTokenService.getMemberInfo();
        String memberId = memberInfo.getMemberId();
        order.setMemberId(memberId);
        String orderNo = SnowflakeIdUtils.nextSnowFlackId(memberInfo.getMobile());
        order.setOrderSn(orderNo);
        order.setReceiverAddressId(vo.getAddressId());
        order.setMemberUsername(memberInfo.getAccount());
        order.setSourceType(OrderEnum.ORDER_SOURCE_PC.getCode());
        order.setStatus(OrderEnum.ORDER_STATUS_WAIT_FOR_PAY.getCode());
        order.setReceiverAddressId(vo.getAddressId());
        //运费
        order.setFreightAmount(BigDecimal.ZERO);
        //默认七天
        order.setAutoConfirmDay(7);
        List<OrderItemEntity> itemList = new ArrayList<>();
        //计算订单总金额
        BigDecimal totalPrice = BigDecimal.ZERO;
        //实际支付金额
        BigDecimal realPrice = BigDecimal.ZERO;
        //促销优化金额（促销价、满减、阶梯价）
        order.setPromotionAmount(BigDecimal.ZERO);
        //积分抵扣金额
        order.setIntegrationAmount(BigDecimal.ZERO);
        //优惠券抵扣金额
        order.setCouponAmount(BigDecimal.ZERO);
        //可获得的积分、成长值
        order.setIntegration(1);
        order.setGrowth(1);
        //发票
        order.setBillType(0);
        //确认收货状态
        order.setConfirmStatus(0);
        //下单时使用的积分
        order.setUseIntegration(0);
        //获取sku优惠信息
        CouponFeignQuery couponFeignQuery = new CouponFeignQuery();
        couponFeignQuery.setType(2);
        couponFeignQuery.setSkuIds(esSkuList.stream().map(EsSkuEntity::getSkuId).collect(Collectors.toList()));
        List<Long> historyIdList = new ArrayList<>();
        List<CouponAllFeignResp> couponList = JsonUtils.transToArrayClass(couponFeignService.getCouponDetail(couponFeignQuery), CouponAllFeignResp.class);
        for (GoodsUpVo goodsUpVo : vo.getGoods()) {
            for (EsSkuEntity entity : esSkuList) {
                if (goodsUpVo.getSkuId().equals(entity.getSkuId())) {
                    OrderItemEntity itemEntity = new OrderItemEntity();
                    itemEntity.setMemberId(memberId);
                    itemEntity.setMerchantId(entity.getMerchantId());
                    itemEntity.setOrderSn(orderNo);
                    itemEntity.setSpuId(entity.getSpuId());
                    itemEntity.setSpuName(entity.getSpuTitle());
                    itemEntity.setSkuId(entity.getSkuId());
                    itemEntity.setSpuBrand(entity.getBrandName());
                    itemEntity.setCategoryId(entity.getCategoryId());
                    itemEntity.setSkuPic(entity.getSkuImg());
                    itemEntity.setSkuPrice(entity.getSkuPrice());
                    Long skuCount = getSkuCount(vo.getGoods(), entity.getSkuId());
                    itemEntity.setSkuQuantity(skuCount);
                    //促销分解金额
                    itemEntity.setPromotionAmount(BigDecimal.ZERO);
                    //优惠卷分解金额
                    itemEntity.setCouponAmount(BigDecimal.ZERO);
                    //积分分解金额
                    itemEntity.setIntegrationAmount(BigDecimal.ZERO);
                    //赠送积分、成长值
                    itemEntity.setGiftGrowth(1);
                    itemEntity.setGiftIntegration(1);
                    //sku总价
                    BigDecimal skuTotalPrice = itemEntity.getSkuPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity()));
                    itemEntity.setRealAmount(skuTotalPrice);
                    itemEntity.setSkuAttrsVals(entity.getAttrs().stream().map(EsSkuAttr::getPropertyValue).collect(Collectors.joining(" ")));
                    couponList.stream().filter(item -> item.getSkuId().equals(entity.getSkuId())).findFirst().ifPresent(item -> {
                        //满减规则
                        FullReductionFeignVo reduction = item.getReduction();
                        if (reduction != null && skuTotalPrice.compareTo(reduction.getFullPrice()) >= 0) {
                            itemEntity.setPromotionAmount(itemEntity.getPromotionAmount().add(reduction.getReducePrice()));
                        }
                        //打折活动
                        LadderFeignVo ladder = item.getLadder();
                        if (ladder != null && ladder.getFullCount() <= skuCount) {
                            itemEntity.setPromotionAmount(itemEntity.getPromotionAmount().add(skuTotalPrice.subtract(skuTotalPrice.multiply(ladder.getDiscount()))));
                        }
                        //优惠卷
                        CouponFeignVo coupon = item.getCoupon();
                        if (coupon != null && coupon.getCouponHistoryId() != null && coupon.getMinPoint().compareTo(skuTotalPrice) <= 0) {
                            historyIdList.add(coupon.getCouponHistoryId());
                            itemEntity.setCouponId(coupon.getCouponId());
                            itemEntity.setCouponAmount(coupon.getAmount());
                        }
                        //计算所有优惠活动后应付金额
                        itemEntity.setRealAmount(itemEntity.getRealAmount()
                                .subtract(itemEntity.getPromotionAmount())
                                .subtract(itemEntity.getCouponAmount())
                                .subtract(itemEntity.getIntegrationAmount()));
                    });
                    order.setCouponAmount(order.getCouponAmount().add(itemEntity.getCouponAmount()));
                    order.setPromotionAmount(order.getPromotionAmount().add(itemEntity.getPromotionAmount()));
                    totalPrice = totalPrice.add(skuTotalPrice);
                    realPrice = realPrice.add(itemEntity.getRealAmount());
                    itemList.add(itemEntity);
                }
            }
        }
        order.setTotalAmount(totalPrice);
        order.setPayAmount(realPrice);
        //保存订单
        orderService.save(order);
        //保存订单条目
        orderItemService.saveBatch(itemList);
        //若是从购物车跳转到详情页，需清除已选中的购物车
        if (vo.getType() == 2) {
            memberFeignService.clearHasSelected().valid();
        }
        //锁定库存
        OrderReduceInventoryResp inventoryResp = JsonUtils.transToClass(productFeignService.lockStock(vo.getGoods()), OrderReduceInventoryResp.class);
        if (!inventoryResp.isSuccess()) {
            EsSkuEntity entity = esSkuList.stream().filter(item -> item.getSkuId().equals(inventoryResp.getSkuId())).findFirst().orElseThrow(() -> new BusinessException("提交订单时，获取sku失败"));
            log.error("库存扣减失败,商品spuId:{}, 商品sku编码，skuCode:{}", entity.getSpuId(), inventoryResp.getSkuId());
            String attrValue = entity.getAttrs().stream().map(EsSkuAttr::getPropertyValue).collect(Collectors.joining(" "));
            throw new BusinessException(entity.getSpuTitle() + "，" + attrValue + ",库存不足！请重新选择商品");
        }
        //扣减优惠卷
        if (!CollectionUtils.isEmpty(historyIdList)) {
            CouponReduceVo couponReduceVo = new CouponReduceVo();
            couponReduceVo.setHistoryIds(historyIdList);
            couponReduceVo.setOrderSn(orderNo);
            couponFeignService.couponReduce(couponReduceVo).valid();
        }
        //事务提交完成后，发送消息到mq
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                try {
                    //延时关单
                    rabbitTemplate.convertAndSend(QueueConstant.ORDER_EXCHANGE, QueueConstant.ORDER_CANCEL_ROUTING_KEY, orderNo);
                } catch (Exception e) {
                    log.error("创建订单发送mq异常：orderNo:{}", orderNo, e);
                    //补偿策略;1:顺序写磁盘，定时任务重写发送mq；2：最大努力通知：扫描订单状态，重新灌入mq
                }
            }
        });
    }

    public Long getSkuCount(List<GoodsUpVo> goods, String skuId) {
        for (GoodsUpVo vo : goods) {
            if (vo.getSkuId().equals(skuId)) {
                return vo.getCount();
            }
        }
        return 0L;
    }
}
